package com.aispeech.asr.apis.ssc.data.vo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.mongodb.core.mapping.Document;

import com.aispeech.asr.apis.ssc.data.domain.TaskDoc;
import com.aispeech.asr.comm.data.vo.Result;
import com.aispeech.asr.comm.enums.ErrorCode;
import com.aispeech.asr.comm.utils.BeanUtils;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

import lombok.ToString;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@ToString
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public final class TaskDocInfo {
    int progress;
    List<Map<String, Object>> result;
    private String id;
    private String productId;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Map<String, Object> request;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Map<String, Long> metrics;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Map<String, Object> error;

    public static Result mergeAnnotation(TaskDoc taskDoc) {
    	
    	Map<String, Object> errorMap = taskDoc.getError();
    	if(errorMap != null && errorMap.size()>0 && !"0".equals(errorMap.get("errid").toString()) ) {
    		return Result.fail(Integer.valueOf(errorMap.get("errid").toString()), errorMap.get("error").toString());
    	}
    	
    	TaskDocInfo taskDocInfo = new TaskDocInfo();
    	
    	taskDocInfo.setId(taskDoc.getId());
    	taskDocInfo.setProductId(taskDoc.getProductId());
    	taskDocInfo.setProgress(taskDoc.getProgress());
    	
    	List<Map<String, Object>> results = taskDoc.getResult();
//        for (int i = 0; i < results.size(); i++) {
//            Map<String, Object> row = results.get(i);
//            row.remove("speaker_ssc");
//        }
        taskDocInfo.setResult(results);
    	
    	if ((int) taskDoc.getRequest().getOrDefault("debug", 0) == 1) {
    		taskDocInfo.setMetrics(taskDoc.getMetrics());
    		taskDocInfo.setError(taskDoc.getError());
    		//taskDocInfo.setRequest(taskDoc.getRequest());
    		
    		Map<String, Object> req = new HashMap<>();
            taskDoc.getRequest().forEach((key, value) -> {
                if (!("debug".equals(key) || "useMetrics".equals(key))) {
                    req.put(BeanUtils.humpToSnake(key), value);
                }
            });

            taskDocInfo.setRequest(req);
        }
    	
        return Result.ok(taskDocInfo);
    }

    public String getProductId() {
        return productId;
    }

    public void setProductId(String productId) {
        this.productId = productId;
    }

    public int getProgress() {
        return progress;
    }

    public void setProgress(int progress) {
        this.progress = progress;
    }

    public List<Map<String, Object>> getResult() {
        return result;
    }

    public void setResult(List<Map<String, Object>> result) {
        this.result = result;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Map<String, Object> getRequest() {
        return request;
    }

    public void setRequest(Map<String, Object> request) {
        this.request = request;
        String appId = (String) request.get("appId");

        if (StringUtils.isNotEmpty(appId))
            productId = appId;
    }

    public Map<String, Long> getMetrics() {
        return metrics;
    }

    public void setMetrics(Map<String, Long> metrics) {
        this.metrics = metrics;
    }

    public void addMetric(String type) {
        if (metrics == null) {
            metrics = new HashMap<>();
        }

        metrics.put(type, System.currentTimeMillis());
    }

    public void addMetric(String type, long ts) {
        if (metrics == null) {
            metrics = new HashMap<>();
        }

        metrics.put(type, ts);
    }

    public Map<String, Object> getError() {
        return error;
    }

    public void setError(Map<String, Object> error) {
        this.error = error;
    }

    public void updateError(ErrorCode code) {
        updateError(code.errid, code.error);
    }

    public void updateError(int code, String message) {
        if (error == null)
            error = new HashMap<>();

        error.put("code", code);
        error.put("message", message);
    }

}
